#include "sigmoid_op.h"
#include "../constant.h"
#include "subtract_op.h"
#include "multiply_op.h"
#include "../../factory/factory.h"
#include "../../factory/constant_factory.h"
#include "../../factory/subtract_factory.h"
#include "../../factory/multiply_factory.h"


Sigmoid::Sigmoid(Node* node) : OpNode({node}){
}

vector<Node*> Sigmoid::getGradNodes(Node* grad){
    Factory* factory;
    Shape* shape = getOutShape(); 
    factory = new ConstantFactory(Matrix(shape -> rows, shape -> cols, 1));
    Node* ones = factory -> createNode();
    delete factory;
    factory = new SubtractFactory(ones, this);
    Node* subtract = factory -> createNode();
    delete factory;
    factory = new MultiplyFactory(this, subtract);
    Node* multiply = factory -> createNode();
    delete factory;
    factory = new MultiplyFactory(multiply, grad);
    Node* ret_grad = factory -> createNode();
    delete factory;
    return {ret_grad};
}

void Sigmoid::compute(Context* context){
    auto nodes = *getNodeIn();
    Matrix mat = context -> getFlowedData(nodes[0]);
    context -> setFlowedData(this, 1 / (1 + exp(-1 * mat)));
}
